#include "DiDo.h"

const char* TAG = "DI/DO";

// 消抖:在读取按键当前状态的时候进行消抖
static enum_DIO_level ucReadDi1Level()
{
    static uint8_t now1 = 0;
    static uint8_t old1 = 0;
    static enum_DIO_level Level_now1 = DIO_LEVEL_LOW;
    static uint8_t usCount1 = 0;
    const uint8_t C_shake1 = 3; // 消抖次数
    old1 = now1;
    now1 = (uint8_t)gpio_get_level(GPIO_DI1);
    // ESP_LOGI(TAG, "Di1 old:%d", old1);
    // ESP_LOGI(TAG, "Di1 now:%d", now1);
    //
    if (now1 == old1) {
        usCount1++;
    } else {
        usCount1 = 0;
    }
    if (usCount1 >= C_shake1) // 消抖判断
    {
        usCount1 = 0;
        if (now1 == DIO_LEVEL_CONNECT) {
            Level_now1 = DIO_LEVEL_HIGH; // 消抖后的结果
        } else {
            Level_now1 = DIO_LEVEL_LOW; // 消抖后的结果
        }
    }
    return Level_now1; // 消抖中，返回之前的按键状态
}

// 消抖:在读取按键当前状态的时候进行消抖
static enum_DIO_level ucReadDi2Level()
{
    static uint8_t now2 = 0;
    static uint8_t old2 = 0;
    static enum_DIO_level Level_now2 = DIO_LEVEL_LOW;
    static uint8_t usCount2 = 0;
    const uint8_t C_shake2 = 3; // 消抖次数
    old2 = now2;
    now2 = (uint8_t)gpio_get_level(GPIO_DI2);
    // ESP_LOGI(TAG, "Di2 old:%d", old2);
    // ESP_LOGI(TAG, "Di2 now:%d", now2);
    //
    if (now2 == old2) {
        usCount2++;
    } else {
        usCount2 = 0;
    }
    if (usCount2 >= C_shake2) // 消抖判断
    {
        usCount2 = 0;
        if (now2 == DIO_LEVEL_CONNECT) {
            Level_now2 = DIO_LEVEL_HIGH; // 消抖后的结果
        } else {
            Level_now2 = DIO_LEVEL_LOW; // 消抖后的结果
        }
    }
    return Level_now2; // 消抖中，返回之前的按键状态
}

/**
 * @brief 	a DI, DO initialization.
 * @param	void
 *
 * @return 	none.
 */
static void vDiDo_Init(void)
{
    /* Set the GPIO as a push/pull output */
    gpio_pad_select_gpio(GPIO_DI1);
    gpio_set_direction(GPIO_DI1, GPIO_MODE_INPUT); ///< 检测高电平按键时下拉
    /* Set the GPIO as a push/pull output */
    gpio_pad_select_gpio(GPIO_DI2);
    gpio_set_direction(GPIO_DI2, GPIO_MODE_INPUT); ///< 检测高电平按键时下拉

    /* Set the GPIO as a push/pull output */
    gpio_pad_select_gpio(GPIO_DO1);
    gpio_set_direction(GPIO_DO1, GPIO_MODE_OUTPUT);
    /* Set the GPIO as a push/pull output */
    gpio_pad_select_gpio(GPIO_DO2);
    gpio_set_direction(GPIO_DO2, GPIO_MODE_OUTPUT);

    ESP_LOGI(TAG, "DiDo_init");
}

void vDiDo_task()
{
    uint8_t ucDi1Status = 0;
    uint8_t ucDi2Status = 0;
    uint8_t ucDo1Status = 0;
    uint8_t ucDo2Status = 0;
    vDiDo_Init();
    while (1) {

        // ESP_LOGI(TAG, "DI1:%d", gpio_get_level(GPIO_DI1));
        // ESP_LOGI(TAG, "DI2:%d", gpio_get_level(GPIO_DI2));

        // DI1   DO1  out
        ucDi1Status = ucReadDi1Level();
        if (ucDi1Status == DIO_LEVEL_HIGH) {
            ucDo1Status = 1;
            gpio_set_level(GPIO_DO1, 1);
        } else {
            ucDo1Status = 0;
            gpio_set_level(GPIO_DO1, 0);
        }

        // DI2   DO2  out
        ucDi2Status = ucReadDi2Level();
        if (ucDi2Status == DIO_LEVEL_HIGH) {
            ucDo2Status = 1;
            gpio_set_level(GPIO_DO2, 1);
        } else {
            ucDo2Status = 0;
            gpio_set_level(GPIO_DO2, 0);
        }

        vTaskDelay(200 / portTICK_PERIOD_MS);
    }
}
